#include "serialport.h"

SerialPort::SerialPort() : hSerial(INVALID_HANDLE_VALUE) {}

SerialPort::~SerialPort() {
    close();
}

bool SerialPort::open(const std::wstring& portName, DWORD baudRate, BYTE byteSize, BYTE stopBits, BYTE parity) {
    hSerial = CreateFile(portName.c_str(),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    if (hSerial == INVALID_HANDLE_VALUE) {
        return false;
    }

    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    if (!GetCommState(hSerial, &dcbSerialParams)) {
        CloseHandle(hSerial);
        hSerial = INVALID_HANDLE_VALUE;
        return false;
    }

    dcbSerialParams.BaudRate = baudRate;
    dcbSerialParams.ByteSize = byteSize;
    dcbSerialParams.StopBits = stopBits;
    dcbSerialParams.Parity = parity;

    if (!SetCommState(hSerial, &dcbSerialParams)) {
        CloseHandle(hSerial);
        hSerial = INVALID_HANDLE_VALUE;
        return false;
    }

    return true;
}

void SerialPort::close() {
    if (hSerial != INVALID_HANDLE_VALUE) {
        CloseHandle(hSerial);
        hSerial = INVALID_HANDLE_VALUE;
    }
}

bool SerialPort::write(const char* data, DWORD size) {
    if (hSerial == INVALID_HANDLE_VALUE) {
        return false;
    }

    DWORD bytesWritten;
    return WriteFile(hSerial, data, size, &bytesWritten, NULL) && bytesWritten == size;
}

DWORD SerialPort::read(char* buffer, DWORD bufferSize) {
    if (hSerial == INVALID_HANDLE_VALUE) {
        return 0;
    }

    DWORD bytesRead;
    ReadFile(hSerial, buffer, bufferSize, &bytesRead, NULL);
    return bytesRead;
}

bool SerialPort::isOpen() const {
    return hSerial != INVALID_HANDLE_VALUE;
}
